package com.rent.weixin.controller;

import cn.hutool.core.bean.BeanUtil;
import com.github.wxpay.sdk.WXPayUtil;
import com.rent.weixin.pojo.WxXmlOutMessage;
import com.rent.weixin.service.IWeixinBaseService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author zhang
 * @create 2021/6/19 10:27
 */
@Slf4j
@RestController
@RequestMapping("/wechat/portal")
public class WxPortalController {

    @Autowired
    private IWeixinBaseService weixinBaseService;

    @ResponseBody
    @GetMapping(produces = "text/plain;charset=utf-8")
    public String authGet(@RequestParam(name = "signature", required = false) String signature,
                          @RequestParam(name = "timestamp", required = false) String timestamp,
                          @RequestParam(name = "nonce", required = false) String nonce,
                          @RequestParam(name = "echostr", required = false) String echostr) {
//        log.info("授权接收到来自微信服务器的认证消息：[{}, {}, {}, {}]", signature, timestamp, nonce, echostr);
        if (StringUtils.isAnyBlank(signature, timestamp, nonce)) {
            throw new IllegalArgumentException("请求参数非法，请核实!");
        }
        if (weixinBaseService.checkSignature(timestamp, nonce, signature)) {
            return echostr;
        }
        return "非法请求";
    }

    @ResponseBody
    @PostMapping(produces = "application/xml; charset=UTF-8")
    public String post(@RequestBody String requestBody,
                       @RequestParam("signature") String signature,
                       @RequestParam(name = "encrypt_type", required = false) String encType,
                       @RequestParam("timestamp") String timestamp,
                       @RequestParam("nonce") String nonce) {
//        log.info("接收到来自微信服务器的认证消息：[{}, {}, {}, {}]", signature, timestamp, nonce, encType);
//        log.info("接收到的数据:{}", requestBody);
        if (StringUtils.isAnyBlank(signature, timestamp, nonce)) {
            log.info("参数:{}", encType);
            throw new IllegalArgumentException("请求参数非法，请核实!");
        }
        if (!weixinBaseService.checkSignature(timestamp, nonce, signature)) {
            log.info("参数:{}", encType);
            throw new IllegalArgumentException("非法请求，可能属于伪造的请求！");
        }
        String msg = returnMsgXml(requestBody);
        log.info("回复消息:{}", msg);
        return msg;
    }

    // 回复消息
    private String returnMsgXml(String xmlString) {
        Map<String, String> map = xml_to_map(xmlString);
        if (map == null || map.isEmpty()) return null;
        String event = map.get("Event");
        if ("CLICK".equals(event)) {
            try {
                WxXmlOutMessage message = BeanUtil.fillBeanWithMap(map, new WxXmlOutMessage(), false);
                Map<String, String> outMap = new HashMap<>();
                outMap.put("ToUserName", message.getFromUserName());
                outMap.put("FromUserName", message.getToUserName());
                outMap.put("CreateTime", message.getCreateTime());
                outMap.put("MsgType", "text");
                outMap.put("Content", message.getEventKey());
                return WXPayUtil.mapToXml(outMap);
            } catch (Exception e) {
                log.info("解析异常:{}", e.getMessage());
            }
        } else {
            return String_XML(xmlString);
        }
        return null;
    }

    //字符串转换为XML
    private String String_XML(String xmlString) {
        if (StringUtils.isEmpty(xmlString)) return null;
        try {
            Document document = DocumentHelper.parseText(xmlString);
            return document.asXML();
        } catch (DocumentException e) {
            log.info("解析异常:{}", e.getMessage());
        }
        return null;
    }

    //字符串转换为XML
    private Map<String, String> xml_to_map(String xmlString) {
        if (StringUtils.isEmpty(xmlString)) return null;
        try {
            Map<String, String> map = WXPayUtil.xmlToMap(xmlString);
            if (map.isEmpty()) return null;
            return map;
        } catch (Exception e) {
            log.info("解析异常:{}", e.getMessage());
        }
        return null;
    }

}
